#include <iostream>
#include <vector>
#include <cmath>
#include "Spline.H"

///---------------Necessary Function Information--------------
constexpr Real funB(const Real &_x)
{
    return 1.0 / (1 + 25.0 * _x * _x);
}

constexpr Real funBder(const Real &t)
{
    return -50.0 * t / (1 + 25.0 * t * t) / (1 + 25.0 * t * t);
}

constexpr Real funC(const Real &_x)
{
    return 1.0 / (1 + _x * _x);
}

constexpr Real funCder(const Real t)
{
    return -2.0 * t / (1 +  t * t) / (1 +  t * t);
}

Vec<Real, 2> heartCurve(Real t)
{
    return {sqrt(3) * cos(M_PI*t), 2.0 / 3 * (sqrt(3) * sin(M_PI*t) + sqrt(sqrt(3) * abs(cos(M_PI*t))))};
}

///----------------- Snippets For B ----------------------
void displayErrorConvergence(RealVect rv)
{
    int B_PossibleN[5] = {5, 10, 20, 40, 80};
    for (int i = 0; i < 4; i++)
        std::cout << "N = " << B_PossibleN[i] + 1 << ", error_max = " << rv[i] << ", convergence rate = " << (std::log2(rv[i] / rv[i + 1])) << std::endl;
    std::cout << "N = " << B_PossibleN[4] + 1 << ", error_max = " << rv[4] << std::endl;
};

void plotAgainstRunge_B(std::string str)
{
    using namespace std;
    ofstream outfile("../../output/B_"+str+"Plot.m"); 
    outfile<<"clear;figure(1);\n";
    for(int k=0;k<5;k++)
    {
        ifstream infile("../../output/B_"+str+"_" + std::to_string(k+1)+".m");
        char c;
        while(infile.get(c))
            outfile <<c; 
        infile.close();
        outfile<<"set(h,'linestyle',':','linewidth',1.5);hold on;\n";
    };
    outfile<<"t=-1:0.004:1;x=1./(1+25.0*t.*t);plot(t,x,'color','k','linestyle','--','LineWidth',2.5);hold on;\n";
    outfile<<"set(gca,'FontSize',20);legend = legend('{n=5}','{n=11}','{n=21}','{n=41}','{n=81}','{f(x)}');set(legend,'FontSize',20,'FontName', 'Times New Roman', 'Location','NorthEastOutside');";
    outfile<<"title('Runge."<<str<<"');saveas(1,'Assignment_B_"<<str<<".png');clf(1);";
    outfile.close();
}

///----------------- Snippets For C ----------------------
void plotAgainstRunge_C(std::string str)
{
    using namespace std;
    ofstream outfile("../../output/C_"+str+".m",ios::app); 
    outfile<<"set(h,'linestyle',':','linewidth',1.5);hold on;\n";
    outfile<<"t=-5:0.02:5;x=1./(1+t.*t);plot(t,x,'color','k','linestyle','-','LineWidth',3);hold on;\n";
    outfile<<"figure(1);\n";
    outfile<<"set(gca,'FontSize',20);";
    outfile<<"title('Corollary."<<str<<"');saveas(1,'Assignment_C_"<<str<<".png');clf(1);";
    outfile.close();
}

///----------------- Snippets For E ----------------------
void plotCharacteristics_E(std::vector<Vec<Real, 2> > rvs,std::string str)
{
    using namespace std;
    ofstream outfile("../../output/E_heart_"+str+".m",ios::app);
    outfile<<"set(h,'linestyle',':','linewidth',1.5);hold on;\n";
    outfile<<"x1=[";
    for(int i=0;i<rvs.size();i++)
        outfile<<rvs[i][0]<<",";
    outfile<<"];\n";
    outfile<<"x2=[";   
    for(int i=0;i<rvs.size();i++)
        outfile<<rvs[i][1]<<",";
    outfile<<"];\n";
    outfile<<"plot(x1,x2,'color','k','marker','x','linestyle','none','linewidth',1.5);hold on;\n";
    outfile<<"figure(1);\n";
    outfile<<"set(gca,'FontSize',20);";
    outfile<<"title('HeartCurve."<<str<<"');saveas(1,'Assignment_E_"<<str<<".png');clf(1);";
    outfile.close();
}